package dyyx.util;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

import dyyx.HelloService;

public abstract class WebUtil {

	// private static final Logger LOG = Logger.getLogger(WebUtil.class);

	public static final String VERSION = "dubbo-hello-provider-2019-11-08 15:00";

	
	
	public static final int MAX_SIZE = 1024*1024;
	public static final String TRUE = "true";
	public static final String FALSE = "false";

	public static final String TYPE = "type";
	public static final String NAME = "name";
	public static final String VALUE = "value";
	public static final String RESULT = "result";
	public static final String ERROR = "error";

	public static final String TYPE_STATUS = "status";

	public static final String TYPE_INFO = "info";

	public static final String TYPE_ECHO = "echo";
	
	public static final String TYPE_CONFIG = "config";
	
	public static final String TYPE_DUBBO_STATUS = "dubbo_status";



	private static final Set<String> TYPES = new HashSet<String>();

	private static final AtomicLong seq = new AtomicLong(0);

	public static final Map<String, String> dataMap = new ConcurrentHashMap<String, String>();
	
	private static volatile String webRootDir = null;
	

	static {
		TYPES.add(TYPE_STATUS);
		TYPES.add(TYPE_INFO);
		TYPES.add(TYPE_ECHO);
		TYPES.add(TYPE_CONFIG);
		TYPES.add(TYPE_DUBBO_STATUS);


	}

	public static String toJsonString(Object obj) {
		if (obj == null) {
			return null;
		}
		return JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.PrettyFormat,
				SerializerFeature.IgnoreErrorGetter);

	}

	public static Boolean getBoolean(String str) {
		if (TRUE.equals(str)) {
			return true;
		}
		if (FALSE.equals(str)) {
			return false;
		}

		return null;
	}

	public static boolean isBlank(String str) {
		if (str == null) {
			return true;
		}
		if (str.length() <= 0) {
			return true;
		}

		return false;
	}

	public static String get(HttpServletRequest request, String name) {
		if (request == null || name == null) {
			return null;
		}
		String str = request.getParameter(name);
		if (str != null) {
			str = str.trim();
		}
		return str;
	}

	public static int getInt(HttpServletRequest request, String name) {
		String str = get(request, name);
		return getInt(str);
	}

	public static long getLong(HttpServletRequest request, String name) {
		String str = get(request, name);
		return getLong(str);
	}

	public static int getInt(String str) {
		try {
			return Integer.parseInt(str);
		} catch (Throwable e) {
			return 0;
		}
	}

	public static long getLong(String str) {
		try {
			return Long.parseLong(str);
		} catch (Throwable e) {
			return 0;
		}
	}

	public static void run(HttpServletRequest request, Map<String, Object> context) throws Exception {
		String type = get(request, TYPE);
		if (type == null || type.length() <= 0) {
			type = TYPE_STATUS;
		}

		if (!TYPES.contains(type)) {
			context.put(ERROR, "type error");
			return;
		}

		context.put(TYPE, type);

		// echo
		if (TYPE_STATUS.equals(type)) {
			run_status(request, context);

		} else {

			try {
				String methodName = "run_" + type;
				Method method = WebUtil.class.getDeclaredMethod(methodName, HttpServletRequest.class, Map.class);
				method.setAccessible(true);
				method.invoke(null, request, context);
			} catch (Throwable e) {
				// e.printStackTrace();
				context.put(ERROR, e + "");
				context.put("errorList", CommUtil.getErrorInfo(e));
			}

		}

	}

	private static void run_status(HttpServletRequest request, Map<String, Object> context) {
		context.put(RESULT, RunStatusUtil.runStatus);

	}
	

	private static void run_dubbo_status(HttpServletRequest request, Map<String, Object> context) {
		context.put(RESULT, DubboStatusUtil.getStatus());

	}

	private static void run_info(HttpServletRequest request, Map<String, Object> context) throws Exception {
		// context.put(RESULT, RunStatusUtil.runStatus);

		Map<String, Object> data = new HashMap<String, Object>();

		data.put("version", VERSION);

		// data.put("config", ConfigUtil.getAllConfig());

		data.put("appConfig", AppConfigUtil.getInfo());
		
		data.put("echoSleepTime", EchoUtil.sleepTime);


		context.put(RESULT, data);
	}

	private static void run_echo(HttpServletRequest request, Map<String, Object> context) throws Exception {

		long start = System.currentTimeMillis();

		try {
			final HelloService service = WebAppContextUtil.getHelloService();

			if (service == null) {

				RunStatusUtil.updateCount("helloServiceNull");
				context.put(ERROR, "service is null");

				return;
			}

			String result = service.echo();
			context.put(RESULT, result);

			long end = System.currentTimeMillis();
			long time = end - start;
			RunStatusUtil.logTime("echoTime", time);

		} catch (Throwable e) {

			context.put(ERROR, "echo_error_" + e);

			long end = System.currentTimeMillis();
			long time = end - start;
			RunStatusUtil.logTime("echoErrorTime", time);

			RunStatusUtil.logError("runEchoError", e);
		}

	}
	
	private static void run_config(HttpServletRequest request, Map<String, Object> context) {
		String name = get(request, NAME);
		String value = get(request, VALUE);

		if (isBlank(name)) {
			context.put(ERROR, "name blank");
			return;
		}

		if (isBlank(value)) {
			context.put(ERROR, "value blank");
			return;
		}

		if ("echoSize".equals(name)) {

			int tmp = getInt(value);
			if (tmp < 10 || tmp > MAX_SIZE) {
				context.put(ERROR, "echoSize error");
				return;
			}

			AppConfigUtil.echoSize = tmp;

			context.put(RESULT, name + " set to " + tmp);

			return;
		}
		
		if ("echoSleepTime".equals(name)) {

			int tmp = getInt(value);
			if (tmp <=0 || tmp > 10000) {
				context.put(ERROR, "echoSleepTime error");
				return;
			}

			EchoUtil.sleepTime = tmp;

			context.put(RESULT, name + " set to " + tmp);

			return;
		}
		
	}
	
	public static void setWebRootDir(String dir){
		if(CommUtil.isBlank(dir)){
			return;
		}
		if(webRootDir!=null){
			return;
		}
		webRootDir = dir;
	}
	
	public static String getWebRootDir(){
		return webRootDir;
	}
	
	public static void doSleep(long time){
		if(time<=0){
			return;
		}
		try{
			
			Thread.sleep(time);
			
		}catch(Throwable e){
			//
		}
	}

}
